/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.ipercube.model;

import java.util.ArrayList;
import java.util.List;

/**
 *
 * @author tartur
 */
public class Node<T, V> {

    private int depth = -1;
    private V value;
    private T node;
    private Node<T, V> parent;
    private List<Node<T, V>> children = null;

    public Node(Node<T, V> parent, T node, V value) {
        this.node = node;
        this.value = value;
        this.parent = parent;
        children = new ArrayList();
    }

    protected Node<T, V> createChild(T node, V value) {
        return new Node<T, V>(this, node, value);
    }

    public int getDepth() {
        return depth;
    }

    public void setDepth(int d) {
        depth = d;
        for (Node<T, V> node : children) {
            if(node != null)
                node.setDepth(d+1);
        }
    }

    public void removeChild(Node<T, V> node) {
        if (getChildren().contains(node)) {
            if (getChildren().remove(node)) {
                node.setDepth(0);
            }
        }
    }

    public Node<T, V> addChild(T child, V value) {
        Node<T, V> chNode = createChild(child, value);
        chNode.depth = this.depth + 1;
        getChildren().add(chNode);
        return chNode;
    }

    public Node<T, V> getChild(int index) {
        return getChildren().get(index);
    }

    public Node<T, V> getChild(T node) {
        Node<T, V> chNode = null;
        for (Node<T, V> child : getChildren()) {
            if (child.equals(node)) {
                chNode = child;
                break;
            }
        }
        return chNode;
    }

    public List<Node<T, V>> getChildren() {
        return children;
    }

    public boolean isLeaf() {
        return children.isEmpty();
    }

    public V getValue() {
        return value;
    }

    public T getNode() {
        return node;
    }

    public Node<T, V> getParent() {
        return parent;
    }

    @Override
    public int hashCode() {
        return node.hashCode();
    }

    @Override
    public boolean equals(Object obj) {
        if (obj instanceof Node) {
            obj = ((Node) obj).node;
        }
        if (!node.getClass().isInstance(obj)) {
            return false;
        }
        return node.equals(obj);
    }
}